<?php

declare(strict_types=1);

namespace App\CustHub\Service;

use App\Common\Robot\Robot;
use App\CustHub\Constants\ContactSourceConstants;
use App\CustHub\Constants\OpSchemeTypeConstants;
use App\CustHub\Constants\RoomInviteLogTypeConstants;
use App\CustHub\Constants\SendConfigConstants;
use App\CustHub\Helpers\TagReplacer;
use App\CustHub\Mapper\ChContactBlackMapper;
use App\CustHub\Mapper\ChContactMapper;
use App\CustHub\Mapper\ChCorpMapper;
use App\CustHub\Mapper\ChOpSchemeGroupMapper;
use App\CustHub\Mapper\ChOpSchemeMapper;
use App\CustHub\Mapper\ChOpSchemeRobotMapper;
use App\CustHub\Mapper\ChRobotMapper;
use App\CustHub\Mapper\ChRoomInviteActiveRoomMapper;
use App\CustHub\Model\ChContact;
use App\CustHub\Model\ChEmployee;
use App\CustHub\Model\ChOpScheme;
use App\CustHub\Model\ChOpSchemeRobot;
use App\CustHub\Model\ChRobot;
use App\CustHub\Model\ChRoom;
use App\CustHub\Model\ChRoomInviteActiveRoom;
use App\CustHub\Model\ChRoomInviteLog;
use App\CustHub\Model\ChRoomInviteSendTask;
use App\CustHub\Traits\OpSchemeTrait;
use App\Robot\Dto\CommonJobDto;
use App\Robot\Job\CommonJob;
use App\Robot\Service\RobotApiService;
use Carbon\Carbon;
use FriendsOfHyperf\Lock\Exception\LockTimeoutException;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Model;
use Hyperf\Di\Annotation\Inject;
use Mine\Abstracts\AbstractService;
use Mine\Annotation\DeleteCache;
use Mine\Annotation\Transaction;
use Mine\Exception\NormalStatusException;
use function FriendsOfHyperf\Lock\lock;
use function Hyperf\Collection\collect;
use function Hyperf\Collection\data_get;
use function Hyperf\Coroutine\co;
use function Hyperf\Stringable\str;
use function Hyperf\Support\optional;


/**
 * 关键词拉群
 */
class ChAutoAcceptFriendService extends AbstractService
{
    use OpSchemeTrait;

    public $mapper;
    public $groupMapper;

    protected int $type = OpSchemeTypeConstants::AUTO_ACCEPT;

    #[Inject]
    protected ChOpSchemeRobotMapper $schemeRobotMapper;

    #[Inject]
    protected ChContactMapper $contactMapper;

    #[Inject]
    protected ChRobotMapper $robotMapper;

    #[Inject]
    protected ChContactMapper $chContactMapper;

    #[Inject]
    protected ChCorpMapper $ChCorpMapper;

    #[Inject]
    protected ChContactBlackMapper $ChContactBlackMapper;

    #[Inject]
    protected ChRoomInviteActiveRoomMapper $inviteActiveRoomMapper;

    public function __construct(ChOpSchemeMapper $mapper,ChOpSchemeGroupMapper $groupMapper)
    {
        $this->mapper = $mapper;
        $this->groupMapper = $groupMapper;
    }


    public function handleSearch(Builder $query, array $params): Builder
    {
        $group_id = data_get($params, 'group_id');
        $keyword = data_get($params, 'keyword');
        if(filled($group_id)){
            $query->where('group_id','=',$group_id);
        }
        if(filled($keyword)){
            $query->where('name','like', "{$keyword}%");
        }
        return $query;
    }

    public function afterSave(int $schemeId,array $data): void
    {

    }

    public function afterUpdate(int $schemeId,array $data): void
    {

    }

    /**
     * 获取详情
     * @param array $params
     * @return Model|ChOpScheme|string|Builder|null
     */
    public function getInfo(array $params): Model|ChOpScheme|string|Builder|null
    {
        $info = $this->mapper->findById($params['id']);

        if(empty($info)){
            throw new NormalStatusException('请选择方案');
        }

        $cfg = $info->cfg;

        if($cfg['type'] == 0){
            $fixedMembers = $cfg['fixed_members'];
            $fixedMemberList = [];
            foreach ($fixedMembers as $fixedMember){
                $robotInfo = $this->robotMapper->findById($fixedMember['robot_id']);
                $memberNicknames = ChContact::query()
                    ->where('robot_id',$fixedMember['robot_id'])
                    ->whereIn('user_id',$fixedMember['user_ids'])
                    ->pluck('nickname')
                    ->toArray();
                $fixedMemberList[] = [
                    'robot_id' => $robotInfo->id,
                    'robot_nickname' => $robotInfo->nickname,
                    'robot_avatar' => $robotInfo->avatar,
                    'robot_user_id' => $robotInfo->user_id,
                    'contact_name' => implode(',',$memberNicknames)
                ];
            }
            $cfg['fixed_member_list'] = $fixedMemberList;

            $cfg['employee_list'] = [];
            if(!empty($cfg['employee_user_ids'])){
                $employeeUserIds = $cfg['employee_user_ids'];
                $cfg['employee_list'] = ChEmployee::query()
                    ->select(['id','nickname','real_name','avatar_url','corp_name','user_id'])
                    ->where('main_uid',$params['main_uid'])
                    ->whereIn('user_id',$employeeUserIds)
                    ->get()->toArray();
            }
        }else{
            //多客户
            $roomCfg = $cfg['room_cnf'];

            $group_pull_data = $roomCfg['group_pull_data'];

            $crowd_id = array_column($group_pull_data,'crowd_id');

            $roomList = ChRoom::query()
                ->select(['room_wxid','room_name','room_avatar_url'])
                ->where('main_uid',$params['main_uid'])
                ->whereIn('room_wxid',$crowd_id)
                ->get()->toArray();

            $roomListMap = array_column($roomList,null,'room_wxid');

            foreach ($group_pull_data as $k=>$item){
                $room = $roomListMap[$item['crowd_id']] ?? [];
                if(!empty($room)){
                    $group_pull_data[$k]['room_name'] = $room['room_name'];
                    $group_pull_data[$k]['room_avatar_url'] = $room['room_avatar_url'];
                }else{
                    unset($group_pull_data[$k]);
                }
            }

            $groupMembers = $roomCfg['group_members'];
            $groupMemberList =[];
            foreach ($groupMembers as $groupMember){
                $robotInfo = $this->robotMapper->findById($groupMember['robot_id']);
                $memberNicknames = ChContact::query()
                    ->where('robot_id',$groupMember['robot_id'])
                    ->whereIn('user_id',$groupMember['user_ids'])
                    ->pluck('nickname')
                    ->toArray();
                $groupMemberList[] = [
                    'robot_id' => $robotInfo->id,
                    'robot_nickname' => $robotInfo->nickname,
                    'robot_avatar' => $robotInfo->avatar,
                    'robot_user_id' => $robotInfo->user_id,
                    'contact_name' => implode(',',$memberNicknames)
                ];
            }
            $roomCfg['group_pull_data'] = $group_pull_data;
            $roomCfg['group_member_list'] = $groupMemberList;
            $roomCfg['employee_list'] = [];
            if(!empty($roomCfg['employee_user_ids'])){
                $employeeUserIds = $roomCfg['employee_user_ids'];
                $roomCfg['employee_list'] = ChEmployee::query()
                    ->select(['id','nickname','real_name','avatar_url','corp_name','user_id'])
                    ->where('main_uid',$params['main_uid'])
                    ->whereIn('user_id',$employeeUserIds)
                    ->get()->toArray();
            }

            $cfg['room_cnf'] = $roomCfg;

        }
        $info->cfg = $cfg;
        return $info;
    }



    /**
     * 删除方案
     * @param mixed $id
     * @return bool
     * @throws \Exception
     */
    #[DeleteCache("ch_op_scheme:id_#{id}"),Transaction]
    public function deleteScheme(mixed $id): bool
    {
        $scheme = $this->mapper->model::query()->find($id);
        if ($scheme) {
            ChOpSchemeRobot::query()->where('scheme_id',$id)->delete();
            $scheme->delete();

            //删除邀请日志
            ChRoomInviteLog::query()
                ->where('scheme_id',$id)
                ->whereIn('type',[RoomInviteLogTypeConstants::TYPE_KEYWORD_SINGLE,RoomInviteLogTypeConstants::TYPE_KEYWORD_MULTI])
                ->delete();

            //删除邀请发送任务
            ChRoomInviteSendTask::query()
                ->where('scheme_id',$id)
                ->whereIn('scheme_type',[RoomInviteLogTypeConstants::TYPE_KEYWORD_SINGLE,RoomInviteLogTypeConstants::TYPE_KEYWORD_MULTI])
                ->delete();

            //删除生效群
            ChRoomInviteActiveRoom::query()
                ->where('scheme_id',$id)
                ->where('scheme_type',RoomInviteLogTypeConstants::TYPE_KEYWORD_MULTI)
                ->delete();
        }
        return true;
    }

    public function AcceptFriendQueue(array $params): void
    {
        var_dump('延迟队列执行自动接受好友请求。。。');
        $robotInfo = $this->robotMapper->findById($params['robot_id']);
        $service = make(Robot::class, [$robotInfo->server_id, $robotInfo->uuid])->gateway();
        $service->agreeContact((string)$params['user_id'],(string)$params['corp_id']);
    }

    public function AutoAcceptFriendQueue(array $params): void
    {
        var_dump('休眠后队列执行自动接受好友请求。。。');
        $robotInfo = $this->robotMapper->findById($params['robot_id']);
        $this->AutoAcceptFriend($robotInfo,$params['data']);
    }

    public function AutoAcceptFriend(ChRobot $robotInfo,array $data): bool
    {
        //查询机器人对应的方案
        $robotId=$robotInfo->id;
        $schemeList=container()->get(ChOpSchemeRobotMapper::class)->findRobotScheme($robotId,OpSchemeTypeConstants::AUTO_ACCEPT);
        if($schemeList ->isEmpty()){
            return false;
        }
        $pass=false;
        $config=null;
        $corp_id=!empty($data['corp_id'])?$data['corp_id']:'';

        foreach ($schemeList as $scheme){
            $config=$scheme->scheme->cfg;
            //判断接受上限
            if($config['limit']){
                $contactTotal=container()->get(ChContactMapper::class)->model::query()->where('robot_id',$robotId)->where('create_time',">",$scheme->created_at->timestamp)->count();
                if($contactTotal >= $config['limit_number']){
                    continue;
                }
            }
            //判断休眠时间
            $now = Carbon::now();
            if($config['sleep_period_switch']){
                $isSleep=false;
                $end=null;
                $config['sleep_period_cfg']=json_decode($scheme->scheme->cfg['sleep_period_cfg'],true);
                foreach ($config['sleep_period_cfg'] as $item){
                    $startTime = Carbon::parse($item['start_time']);
                    $endTime = Carbon::parse($item['end_time']);
                    // 处理跨天情况
                    if ($startTime->gt($endTime)) {
                        // 跨天情况：开始时间 > 结束时间（如 23:00 > 09:00）
                        if ($now->between($startTime, $startTime->copy()->endOfDay()) ||
                            $now->between($endTime->copy()->startOfDay(), $endTime)) {
                            $isSleep = true;
                            // 计算实际的结束时间（次日）
                            $sleepEndTime = $endTime->copy()->addDay();
                        }
                    } else {
                        // 正常情况：开始时间 <= 结束时间
                        if ($now->between($startTime, $endTime)) {
                            $isSleep = true;
                            $sleepEndTime = $endTime;
                        }
                    }
                }
                if($isSleep){
                    //插入延迟队列执行,休眠时间过后2分钟后执行
                    $delay=($sleepEndTime->timestamp + 120)+rand(10,99) - time();
                    var_dump('休眠中延迟执行'.$delay);
                    container()->get(LowQueueService::class)->push(new CommonJob(new CommonJobDto(
                        classname: ChAutoAcceptFriendService::class,
                        method: 'AutoAcceptFriendQueue',
                        data:[
                            'robot_id' => $robotId,
                            'data' => $data,
                        ]
                    )),$delay);
                    return false;
                }
            }

            //条件判断
            //1.来源
            var_dump($data);
            var_dump('条件判断');
            $add_source=!empty($data['source_info']['add_source'])?$data['source_info']['add_source']:0;
            $config['source_cfg']=json_decode($config['source_cfg'],true);
            $source_types=$config['source_cfg']['source_types'];
            if(in_array(ContactSourceConstants::FRIEND_CARD_SHARE,$source_types)){
                $source_types[]=ContactSourceConstants::FRIEND_CARD_SHARE_WECHAT;
            }
            if(in_array(ContactSourceConstants::PHONE_SEARCH,$source_types)){
                $source_types[]=ContactSourceConstants::PHONE_SEARCH_WECHAT;
            }
            if(in_array(ContactSourceConstants::IN_ROOM,$source_types)){
                $source_types[]=ContactSourceConstants::IN_ROOM_WECHAT;
            }
            if(in_array(ContactSourceConstants::SCAN_QR_CODE,$source_types)){
                $source_types[]=ContactSourceConstants::SCAN_QR_CODE_WECHAT;
            }
            if($config['source_cfg']['accept_type']==2 && !in_array($add_source,$source_types)){
                continue;
            }
            //2.昵称
            $nickname = decodeIfBase64($data['nickname']);
            $config['nick_cfg']=json_decode($scheme->scheme->cfg['nick_cfg'],true);
            if ($config['nick_cfg']['accept_type'] == 2 && in_array($nickname, $config['nick_cfg']['nick_words'])) {
                continue;
            }
            //3.验证消息
            $verify = decodeIfBase64($data['apply_reason']);
            $config['verify_cfg']=json_decode($scheme->scheme->cfg['verify_cfg'],true);
            if ($config['verify_cfg']['accept_type'] == 2 && !in_array($verify, $config['verify_cfg']['verify_words'])) {
                continue;
            }
            //4.企业
            $company = !empty($data['corp_name'])?$data['corp_name']:'微信';
            //查不到企业直接拒
            if(empty($company)){
                continue;
            }
            $config['enterprise_cfg']=json_decode($scheme->scheme->cfg['enterprise_cfg'],true);
            if($config['enterprise_cfg']['accept_type']==3  || ($config['enterprise_cfg']['accept_type']==2 && in_array($company,$config['enterprise_cfg']['enterprise_words']))){
                continue;
            }
            //黑名单用户
            if($config['blacklist']==3){
                $black=$this->ChContactBlackMapper->first(['uid'=>$scheme->uid,'user_id'=>$data['user_id']]);
                if(!empty($black)) continue;
            }
            $pass = true;
            break;
        }
        var_dump('自动通过好有请求结果'.$pass);

        if($pass){
            //自动通过好友请求
            $delay=rand((int)$config['accept_min'],(int)$config['accept_max']);
            container()->get(LowQueueService::class)->push(new CommonJob(new CommonJobDto(
                classname: ChAutoAcceptFriendService::class,
                method: 'AcceptFriendQueue',
                data:[
                    'robot_id' => $robotId,
                    'user_id' => $data['user_id'],
                    'corp_id' => $corp_id
                ]
            )),$delay);
            return true;
        }
        return false;
    }




}